class Print < ActiveRecord::Base
  require 'csv'

  #Txxx variables temporaires
  #Zxxx variables par Zone
  #Pxxx variables par Parcelle
  
  attr_accessor :Tcols, :Tfactures, :Tlabours, :Tpulves,
                :Parcelles, :Plabours, :Ppulves, :Pfactures,
                :Zones, :Zlabours, :Zpulves, :Zfactures

  def initialize
  end

  def get_value_or_blank(var, value)
    val = var[value.to_sym]
    return (pretty_csv(val))
  end

  #TODO deja declaré dans application helper commment ne pas dupliquer cette methode?
  def pretty_csv(val)
    precision = 1
    return nil if (val.equal?(0))
    return nil if (val == 0.0)
    return val.to_i if (val == val.to_i)
    return val if precision == 0
    return (val * 10 ** precision).round.to_f / 10 ** precision
  end
  
  def calculate(col_model)
    @parcelles = Parcelle.find(:all)
    @labours = Labour.find(:all)
    @pulves = Pulve.find(:all)
    @factures = Facture.find(:all, :order => "category_id")
    @types = Category.find_all_by_upcategory_id(Upcategory.find_by_name('facture'))
    
#Parcelles
    init_cols(col_model)
    init_cols(col_model)
    init_factures(col_model)
    init_pulves(col_model)
    init_labours(col_model)

    run_labours(col_model)
    run_pulves(col_model)
    run_factures(col_model)
    run_totaux(col_model)
  end

  def write_csv
    @labours = Labour.find(:all)
    @pulves = Pulve.find(:all)
    @factures = Facture.find(:all, :order => "category_id")

    nb_cols_before = 5
    nb_cols = self.Tcols[:length]
    nb_cols_total = nb_cols_before + nb_cols
    row = []
    writer = CSV.open('csvfile.csv', 'w')

  # line 1
    row.clear
    nb_cols_before.times do row << nil end
    self.Tcols[:ids].each do |id|
      row << self.Tcols[id][:id].to_s + ' - '+ self.Tcols[id][:name]
      row << (self.Tcols[id][:surface].to_s + ' Ha')
    end
    writer << row

  #line 2
    row.clear
    row = [nil, 'nom', 'passage Ha', 'total/Ha', 'total'] 
    entete = ['c/Ha', 'total']
    (nb_cols).times { row += entete }
    writer << row
    
  #Labours
    #tete  
    row.clear
    ((nb_cols * 2)+ nb_cols_before).times { row << nil }
    writer << row
    
    row.clear
    row = ['Labours']
    ((nb_cols * 2)+ nb_cols_before - 1 ).times { row << nil }
    writer << row
    
    #each labour
    row.clear
    @labours.each do |labour|
      dep = self.Tlabours[labour.id]
      cell = labour.parcelles.length.to_s
      cell += ' p - '
      cell += pretty_csv(dep[:surface_total]).to_s
      cell += ' ha'
      row << cell
      row << labour.name
      row << pretty_csv(dep[:cout_ha_passage]).to_s
      row << pretty_csv(dep[:cout_ha_total]).to_s
      self.Tcols[:ids].each do |id|
        row <<  get_value_or_blank(dep[id], "cout_ha")
        row <<  get_value_or_blank(dep[id], "cout_total") 
      end
      writer << row
      row.clear
    end
    
    #Total labour
    row.clear
    row << ['Total Labour']
    (nb_cols_before - 2).times { row << nil }
    
    row << pretty_csv(self.Tlabours[:cout_total])
    self.Tcols[:ids].each do |id|
      row <<  get_value_or_blank(self.Tcols[id][:labours], "cout_ha")
      row <<  get_value_or_blank(self.Tcols[id][:labours], "cout_total")
    end
    writer << row
    row.clear

    
  #Pulves
    #tete  
    row.clear
    ((nb_cols * 2)+ nb_cols_before).times { row << nil }
    writer << row
    
    row.clear
    row = ['Pulves']
    ((nb_cols * 2)+ nb_cols_before - 1 ).times { row << nil }
    writer << row
    
    #each pulve
    row.clear
    @pulves.each do |pulve|
      dep = self.Tpulves[pulve.id]
      cell = pulve.parcelles.length.to_s
      cell += ' p - '
      cell += pretty_csv(dep[:surface_total]).to_s
      cell += ' ha'
      row << cell
      row << pulve.name
      
      cell = pretty_csv(dep[:cout_ha_passage]).to_s
      cell += ' + '
      cell += pretty_csv(dep[:cout_ha_produit]).to_s
      row << cell
      row << pretty_csv(dep[:cout_ha_total]).to_s
      self.Tcols[:ids].each do |id|
        row <<  get_value_or_blank(dep[id], "cout_ha")
        row <<  get_value_or_blank(dep[id], "cout_total") 
      end
      writer << row
      row.clear
    end   
    
    #Total pulve
    row.clear
    row << ['Total Pulves']
    (nb_cols_before - 2).times { row << nil }
    
    row << pretty_csv(self.Tpulves[:cout_total])
    self.Tcols[:ids].each do |id|
      row <<  get_value_or_blank(self.Tcols[id][:pulves], "cout_ha")
      row <<  get_value_or_blank(self.Tcols[id][:pulves], "cout_total")
    end
    writer << row
    row.clear

  #Factures
    #tete  
    row.clear
    ((nb_cols * 2)+ nb_cols_before).times { row << nil }
    writer << row
    
    row.clear
    row = ['Factures']
    ((nb_cols * 2)+ nb_cols_before - 1 ).times { row << nil }
    writer << row
    
    #each facture
    row.clear
    @factures.each do |facture|
      dep = self.Tfactures[facture.id]
      cell = facture.parcelles.length.to_s
      cell += ' p - '
      cell += pretty_csv(dep[:surface_total]).to_s
      cell += ' ha'
      row << cell
      row << facture.name
     
      row << pretty_csv(dep[:cout_ha]).to_s
      row << pretty_csv(dep[:cout_total]).to_s
      self.Tcols[:ids].each do |id|
        row <<  get_value_or_blank(dep[id], "cout_ha")
        row <<  get_value_or_blank(dep[id], "cout_total") 
      end
      writer << row
      row.clear
    end   

    #Total facture par type
      for type in @types
        row.clear
        row << 'Total '+ type.name
        (nb_cols_before - 2).times { row << nil }
        
        row << pretty_csv(self.Tfactures[:cout_total][type.name]).to_s
        self.Tcols[:ids].each do |id|
          row <<  pretty_csv(self.Tcols[id][:total][:cout_ha][type.name])
          row <<  pretty_csv(self.Tcols[id][:total][:cout_total][type.name])
        end
        writer << row
        row.clear
      end
    
    #Total facture
    row.clear
    row << ['Total Factures']
    (nb_cols_before - 2).times { row << nil }
    
    row << pretty_csv(self.Tfactures[:cout_total][:sum])
    self.Tcols[:ids].each do |id|
      row <<  get_value_or_blank(self.Tcols[id][:factures][:cout_ha], "sum")
      row <<  get_value_or_blank(self.Tcols[id][:factures][:cout_total], "sum")
    end
    writer << row
    row.clear


    #Total total
    row.clear
    row << ['Total']
    (nb_cols_before - 3).times { row << nil }
    
    row << pretty_csv(self.Tcols[:cout_ha])
    row << pretty_csv(self.Tcols[:cout_total])
    self.Tcols[:ids].each do |id|
      row <<  get_value_or_blank(self.Tcols[id][:total][:cout_ha], "sum")
      row <<  get_value_or_blank(self.Tcols[id][:total][:cout_total], "sum")
    end
    writer << row
    row.clear


  
  
  end
 
  def init_cols(col_model)
    cols = col_model.find(:all)
    types = Category.find_all_by_upcategory_id(Upcategory.find_by_name('facture'))
    rang = 0
    
  #Init Hparcelles 
    self.Tcols = {}
    self.Tcols[:ids] = []
    
    for col in cols
      self.Tcols[col.id] = {}
      self.Tcols[col.id][:pulves] = {}
      self.Tcols[col.id][:labours] = {}
      self.Tcols[col.id][:factures] = {}
      self.Tcols[col.id][:total] = {}
      
      self.Tcols[col.id][:total][:cout_ha] = {}
      self.Tcols[col.id][:total][:cout_total] = {}
      self.Tcols[col.id][:factures][:cout_ha] = {}
      self.Tcols[col.id][:factures][:cout_total] = {}

      self.Tcols[:cout_total] = 0   # derniere case somme de tout les totaux
      self.Tcols[:cout_ha] = 0   # derniere case somme de tout les totaux ha
      self.Tcols[:length] = cols.length
      self.Tcols[:ids] << col.id
      
      self.Tcols[col.id][:id] = col.id
      self.Tcols[col.id][:name] = col.name
      self.Tcols[col.id][:surface] = col.surface
      
      
      rang += 1
      self.Tcols[col.id][:rang] = rang  
      self.Tcols[col.id][:labours][:cout_ha] = 0
      self.Tcols[col.id][:labours][:cout_total] = 0
      self.Tcols[col.id][:pulves][:cout_ha] = 0
      self.Tcols[col.id][:pulves][:cout_total] = 0
      
      self.Tcols[col.id][:factures][:cout_total][:sum] = 0  
      self.Tcols[col.id][:factures][:cout_ha][:sum] = 0  
      self.Tcols[col.id][:total][:cout_total][:sum] = 0  
      self.Tcols[col.id][:total][:cout_ha][:sum] = 0  

      for type in types
        self.Tcols[col.id][:factures][:cout_total][type.name] = 0  
        self.Tcols[col.id][:factures][:cout_ha][type.name] = 0  
        self.Tcols[col.id][:total][:cout_total][type.name] = 0  
        self.Tcols[col.id][:total][:cout_ha][type.name] = 0  
      end
    end
    
  end

  def init_factures(col_model)
    cols = col_model.find(:all)
    @factures = Facture.find(:all, :order => "category_id")
    @types = Category.find_all_by_upcategory_id(Upcategory.find_by_name('facture'))
    rang = 0    
    
    @Tfactures = Hash.new()
    @Tfactures[:cout_total] = Hash.new()
    @Tfactures[:cout_ha] = Hash.new()
    
    for facture in @factures
      @Tfactures[facture.id] = {:parcelles => {}, :id => facture.id, :name => facture.name, :cout => facture.cout }
      #for parcelle in facture.parcelles
      for col in cols
        hcols = {:name => col.name, :surface => col.surface }  
        @Tfactures[facture.id][:parcelles].store(col.id, hcols)
        @Tfactures[facture.id][col.id] = {:cout_ha => 0, :cout_total => 0 , :cout_sans_charges => 0 }

        @Tfactures[facture.id][:cout_total] = 0 
        @Tfactures[facture.id][:cout_ha] = 0 
        @Tfactures[:cout_total][:sum] = 0 
        @Tfactures[:cout_ha][:sum] = 0 
        
        for type in @types
          @Tfactures[:cout_total][type.name] = 0 
          @Tfactures[:cout_ha][type.name] = 0 
        end
      end
    end
  end
  
  def init_labours(col_model)
  #Init Hlabours 
    cols = col_model.find(:all)
    labours = Labour.find(:all)
    
    @Tlabours = Hash.new()
    @Tlabours[:cout_total] = 0
    @Tlabours[:cout_ha_total] = 0
    for labour in labours
      @Tlabours[labour.id] = {:parcelles => {}, :id => labour.id, :name => labour.name, :cout_total => (labour.cout_ha_passage * 10), :cout_ha_passage => labour.cout_ha_passage}
      for col in cols
        hcols = {:name => col.name, :surface => col.surface }  
        @Tlabours[labour.id][:parcelles].store(col.id, hcols)
        @Tlabours[labour.id][col.id] = {:cout_ha => 0, :cout_total => 0 }
      end
    end
  end

  def init_pulves(col_model)
  #Init Hpulve 
    cols = col_model.find(:all)
    @pulves = Pulve.find(:all)
    
    @Tpulves = Hash.new()
    @Tpulves[:cout_total] = 0
    @Tpulves[:cout_ha_total] = 0
    for pulve in @pulves
      @Tpulves[pulve.id] = {:parcelles => {}, :id => pulve.id, :name => pulve.name, :cout_total => (pulve.cout_ha_passage * 10), :cout_ha_passage => pulve.cout_ha_passage}
      for col in cols
        hcols = {:name => col.name, :surface => col.surface }  
        @Tpulves[pulve.id][:parcelles].store(col.id, hcols)
        @Tpulves[pulve.id][col.id] = {:cout_ha => 0, :cout_total => 0 }
      end
    end
  end

  def run_labours(col_model)
    cols = col_model.find(:all)
    @labours = Labour.find(:all)
  #LABOUR
    for labour in @labours
      for col in cols
        #valeur ha et total pour chaque col affecté a la labour
        cout_ha = labour.get_cout_ha_col(col)
        cout_total = labour.get_cout_total_col(col)
        @Tlabours[labour.id][col.id][:cout_ha] = cout_ha
        @Tlabours[labour.id][col.id][:cout_total] = cout_total
      end
 
      @Tlabours[labour.id][:parcelles_size] = @Tlabours[labour.id][:parcelles].length      
      @Tlabours[labour.id][:cout_ha_total] = labour.get_cout_ha
      @Tlabours[labour.id][:cout_total] = labour.get_cout_total
      @Tlabours[labour.id][:surface_total] = labour.sum_surfaces
      #total labour
      @Tlabours[:cout_total] += @Tlabours[labour.id][:cout_total]
      @Tlabours[:cout_ha_total] += @Tlabours[labour.id][:cout_ha_total]
    end
  end

  def run_pulves(col_model)
    cols = col_model.find(:all)
    for pulve in @pulves
      for col in cols
        #valeur ha et total pour chaque col affecté a la pulve
        cout_ha = pulve.get_cout_ha_col(col)
        cout_total = pulve.get_cout_total_col(col)
        @Tpulves[pulve.id][col.id][:cout_ha] = cout_ha
        @Tpulves[pulve.id][col.id][:cout_total] = cout_total
      end
 
      @Tpulves[pulve.id][:parcelles_size] = @Tpulves[pulve.id][:parcelles].length      
      @Tpulves[pulve.id][:cout_ha_produit] = pulve.get_cout_ha_produit
      @Tpulves[pulve.id][:cout_ha_passage] = pulve.cout_ha_passage
      @Tpulves[pulve.id][:cout_ha_total] = pulve.get_cout_ha
      @Tpulves[pulve.id][:cout_total] = pulve.get_cout_total
      @Tpulves[pulve.id][:surface_total] = pulve.sum_surfaces
      #total pulve
      @Tpulves[:cout_total] += @Tpulves[pulve.id][:cout_total]
      @Tpulves[:cout_ha_total] += @Tpulves[pulve.id][:cout_ha_total]
    end
  end

  def run_factures(col_model)
    cols = col_model.find(:all)
    for facture in @factures
      for col in cols
        #valeur ha et total pour chaque col
        cout_ha = facture.get_cout_ha_col(col)
        cout_total = facture.get_cout_total_col(col)
        @Tfactures[facture.id][col.id][:cout_ha] = cout_ha
        @Tfactures[facture.id][col.id][:cout_total] = cout_total
      end
      
      total_ha = facture.get_cout_ha
      total = facture.get_cout_total
      @Tfactures[facture.id][:category] = facture.category.name
      @Tfactures[facture.id][:parcelles_size] = @Tfactures[facture.id][:parcelles].length
      @Tfactures[facture.id][:surface_total] = facture.sum_surfaces
      
      #total de la facture
      @Tfactures[facture.id][:cout_total] = total
      @Tfactures[facture.id][:cout_ha] = total_ha
      
      #total des factures
      @Tfactures[:cout_total][:sum] += total
      @Tfactures[:cout_ha][:sum] += total_ha
      
      #totaux par types de factures
      for type in @types
        if (@Tfactures[facture.id][:category].to_s == type.name)
          @Tfactures[:cout_total][type.name] += total
          @Tfactures[:cout_ha][type.name] += total_ha
        end
      end
    end
  end

  def run_totaux(col_model)
    cols = col_model.find(:all)
    
    #TOTAUX PAR PARCELLES
    for labour in @labours
      for col in cols
        cout_ha = @Tlabours[labour.id][col.id][:cout_ha]
        cout_total = @Tlabours[labour.id][col.id][:cout_total]
      
      #somme des labours par col
        @Tcols[col.id][:labours][:cout_ha] += cout_ha
        @Tcols[col.id][:labours][:cout_total] += cout_total
     
      #total des couts par parcelle
        @Tcols[col.id][:total][:cout_ha][:sum] += cout_ha
        @Tcols[col.id][:total][:cout_total][:sum] += cout_total
      end
    end
    
    for pulve in @pulves
      for col in cols
        cout_ha = @Tpulves[pulve.id][col.id][:cout_ha]
        cout_total = @Tpulves[pulve.id][col.id][:cout_total]
      
      #somme des pulves par parcelle
        @Tcols[col.id][:pulves][:cout_ha] += cout_ha
        @Tcols[col.id][:pulves][:cout_total] += cout_total
     
      #total des couts par parcelle
        @Tcols[col.id][:total][:cout_ha][:sum] += cout_ha
        @Tcols[col.id][:total][:cout_total][:sum] += cout_total
      end
    end
    
    for facture in @factures
      for col in cols
        cout_ha = @Tfactures[facture.id][col.id][:cout_ha]
        cout_total = @Tfactures[facture.id][col.id][:cout_total]

        #somme des factures par parcelle
        @Tcols[col.id][:factures][:cout_ha][:sum] += cout_ha
        @Tcols[col.id][:factures][:cout_total][:sum] += cout_total

        #total des couts par parcelle
        @Tcols[col.id][:total][:cout_ha][:sum] += cout_ha
        @Tcols[col.id][:total][:cout_total][:sum] += cout_total

        for type in @types
          if (@Tfactures[facture.id][:category].to_s == type.name)
            @Tcols[col.id][:total][:cout_ha][type.name] += cout_ha
            @Tcols[col.id][:total][:cout_total][type.name] += cout_total
          end
        end
      end    
    end

#SOMME DES TOTAUX
    for col in cols
      @Tcols[:cout_total] += @Tcols[col.id][:total][:cout_total][:sum]
      @Tcols[:cout_ha] += @Tcols[col.id][:total][:cout_ha][:sum]
    end    
  end

  def run_test
    
  end
end

